//
//  BYTimer.m
//  BYTimerDemo
//
//  Created by 崔宝印 on 2018/8/7.
//  Copyright © 2018年 Koolearn. All rights reserved.
//

#import "BYTimer.h"

@implementation BYTimer

static NSMutableDictionary *timerDic;
static dispatch_semaphore_t byTimerSemaphore;

+ (NSString *)doTask:(BYTimerTaskBlock)block
          afterDelay:(NSTimeInterval)delay
        timeInterval:(NSTimeInterval)interval
             repeats:(BOOL)repeats
               async:(BOOL)async
{
    if (!block || delay < 0 || interval <= 0) return nil;
    

    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        timerDic = [NSMutableDictionary dictionary];
        byTimerSemaphore = dispatch_semaphore_create(1);
    });
    dispatch_queue_t queue = async ? dispatch_get_global_queue(0, 0) : dispatch_get_main_queue();
    dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
    dispatch_time_t start = dispatch_time(DISPATCH_TIME_NOW, delay * NSEC_PER_SEC);
    dispatch_source_set_timer(timer, start, interval * NSEC_PER_SEC, 0 * NSEC_PER_SEC);

    dispatch_semaphore_wait(byTimerSemaphore, DISPATCH_TIME_FOREVER);//加锁
    NSString *timerTag = [NSString stringWithFormat:@"BYTimer:%zd",timerDic.count];
    [timerDic setObject:timer forKey:timerTag];
    dispatch_semaphore_signal(byTimerSemaphore);//解锁
    
    dispatch_source_set_event_handler(timer, ^{
        block();
        if (!repeats)
        {
            [BYTimer cancelTimer:timerTag];
        }
    });
    dispatch_resume(timer);
    return timerTag;
}

+ (void)cancelTimer:(NSString *)timerTag
{
    if (!timerTag) return;
    
    dispatch_semaphore_wait(byTimerSemaphore, DISPATCH_TIME_FOREVER);
    dispatch_source_t timer = [timerDic objectForKey:timerTag];
    if (timer)
    {
        dispatch_source_cancel(timer);
        [timerDic removeObjectForKey:timerTag];
    }
    dispatch_semaphore_signal(byTimerSemaphore);
}

@end
